<?php

namespace App\Http\Controllers;

use App\Models\Tag;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Http\Requests\StoreTag;
use Illuminate\Support\Facades\Gate;
use App\Http\Utils\ConstantUtils;

class TagController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $tags = Tag::all();
        return view('tag.list', ['tags' => $tags]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create(Request $request)
    {
        // 是否允许
        // 没有 Gate::can('tag')
        // if (Gate::allows('tag')) {
        if ($request->user()->can('tag')) {
            return view('tag.create');
        }

        $request->session()->flash('noPermission', '1');
        $request->session()->flash('noPermissionMessage', ConstantUtils::NO_PERMISSION);
        return back();
    }

    /**
     * Store a newly created resource in storage.
     * Request $request
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(StoreTag $request)
    {
        // 命名错误包
        // 如果你一个页面中有多个表单，你可以通过命名包来检索特定表单的错误消息。

        /*
        表单的输入控件名称和模型类（数据表）不一致，这种赋值的方式无法通过校验，即使有值传过来，还是报错不能为空。
        $request->name = $request->tagName;
        $request->description = $request->tagDescription;
        $validatedData = $request->validate([
            // 键名必须是与表的字段一致。因为要去数据表进行查询。
            // 'tagName' => 'required|unique:tags|max:255',
            'name' => 'required|unique:tags|max:255',
            'description' => 'required|max:255',
        ]);
        */

        // 只能保持表单控件的 name 和模型类（数据表）一致才行了。
        /*
        $validatedData = $request->validate([
            // 键名必须是与表的字段一致。因为要去数据表进行查询。
            // 'tagName' => 'required|unique:tags|max:255',
            'name' => 'required|unique:tags|max:255',
            'description' => 'required|max:255',
        ]);
        */
        // 或者
        /*$validatedData = $request->validate([
            'name' => ['required','unique:tags','max:255'],
            'description' => ['required','max:255'],
        ]);*/
        // 如果你希望在某个属性第一次验证失败后停止运行验证规则，你需要附加 bail 规则到该属性
        // 'name' => 'bail|required|unique:tags|max:255',

        // 可以自定义错误消息
        /*$validatedData = $request->validate([
            // 键名必须是与表的字段一致。因为要去数据表进行查询。
            // 'tagName' => 'required|unique:tags|max:255',
            'name' => 'required|unique:tags|max:255',
            'description' => 'required|max:255',
        ], [
            'required' => ':attribute 不能为空112233'
        ]);*/


        // 还可以使用 命名错误包
        /*$validatedData = $request->validateWithBag('tags', [
            'name' => ['required','unique:tags','max:255'],
            'description' => ['required','max:255'],
        ]);*/
        // 使用
        // {{ $errors->tags->first('name') }}


        // 另一种方式（创建表单的验证类）
        // php artisan make:request StoreBlogPost
        // 位于 app/Http/Requests/StoreBlogPost，且是 Illuminate\Foundation\Http\FormRequest 的子。
        // class FormRequest extends Request implements ValidatesWhenResolved
        // FormRequest 继承了 \Illuminate\Http\Request，所以可以传递给控制器的方法。
        // 具体使用见文档：https://learnku.com/docs/laravel/7.x/validation/7467#f617cd
        $validated = $request->validated();
        // 如果验证通过则继续往下运行，否则验证失败自动跳转回前一个页面。


        // 另一种方式（手动创建验证器--在控制器的方法里，这个有点繁琐，但如果每个方法内的验证不同的话，就好用）
        /*
        $validator = Validator::make($request->all(), [
            'name' => 'required|unique:tags|max:255',
            'description' => 'required',
        ]);
        // 验证，如果失败则进行跳转
        if ($validator->fails()) {
            return redirect('tags/create')
                        ->withErrors($validator)
                        // 还可以将错误消息存储在 命名错误包 中：
                        // ->withErrors($validator, 'mytags')
                        ->withInput();
        }

        // 这种方式还支持 验证后钩子
        $validator = Validator::make($request->all(), [
            'name' => 'required|unique:tags|max:255',
            'description' => 'required',
        ]);
        // 验证后钩子
        $validator->after(function ($validator) {
            if ($this->somethingElseIsInvalid()) {
                $validator->errors()->add('field', 'Something is wrong with this field!');
            }
        });
        // 验证，如果失败则进行跳转
        if ($validator->fails()) {
            return redirect('tags/create')
                        ->withErrors($validator)
                        // 还可以将错误消息存储在 命名错误包 中：
                        // ->withErrors($validator, 'mytags')
                        ->withInput();
        }

        // 还可以自定义错误消息
        $messages = [
            'required' => 'The :attribute field is required.',
            'same'    => 'The :attribute and :other must match.',
            'size'    => 'The :attribute must be exactly :size.',
            'between' => 'The :attribute value :input is not between :min - :max.',
            'in'      => 'The :attribute must be one of the following types: :values',
        ];
        $validator = Validator::make($input, $rules, $messages);
         */

        // 还可以自动重定向（直接调用 validate() 方法）
        /*Validator::make($request->all(), [
            'title' => 'required|unique:tags|max:255',
            'body' => 'required',
        ])->validate();*/
        // 还可以将错误消息存储在 命名错误包 中： ->validateWithBag('tags');


        // 查看错误消息
        /*$errors = $validator->errors();
        // 某字段是否存在错误
        if ($errors->has('email')) {}
        // 查看特定字段的第一个错误消息
        echo $errors->first('email');
        // 获取指定字段的所有错误信息的数组
        foreach ($errors->get('email') as $message) {}
        // 所有错误消息
        foreach ($errors->all() as $message) {}*/



        // $tag = new Tag;
        // var_dump($request->input('tagName'));
        // 只有这个没有值，是 null.
        // var_dump($request->query('tagName'));
        // var_dump($request->post('tagName'));
        // var_dump($request->tagName);
        // $tag->name = $request->tagName;
        // $tag->assignAttributes($request, [
        //         'name' => 'tagName',
        //         'description' => 'tagDescription',
        //     ]);

        // if ($tag->save()) {
        //     Log::info("创建新标签成功");
        //     return redirect('tags');
        // }
    }

    /**
     * Display the specified resource.
     * 既可以使用 ($id) 得到 url中的 id 的值，自己查询后修改。
     * 也可以使用 (Tag $tag) 得到自动查询得到的模型实例，然后修改。
     *
     * @param  \App\Models\Tag  $tag
     * @return \Illuminate\Http\Response
     */
    public function show(Request $request, Tag $tag)
    {
        var_dump($tag);
        return;
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Tag  $tag
     * @return \Illuminate\Http\Response
     */
    public function edit(Tag $tag)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Tag  $tag
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Tag $tag)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Tag  $tag
     * @return \Illuminate\Http\Response
     */
    public function destroy(Tag $tag)
    {
        //
    }
}
